/*******************************************************************************

                        LVGL 输入法总体实现

*******************************************************************************/
#include "lvIME.h"
#include <string.h>


//当前正在运行的输入法类型, 负表示没有在输入法状态
signed char lvIME_RType = -1;
//用户带入的支持输入法类型
static unsigned char _OrgTypeMask;
//用户带入的父窗口
static lv_obj_t * _pOrgParent;

lv_style_t TMStyle_NullBG;       //无边界全铺满样式
lv_style_t TMStyle_BtnFull;       //矩形按钮铺满样式
lv_style_t TMStyle_HalfOpa;       //半透明样式
//---------------------------初始化输入法样式--------------------------------
//进入lvIME时须调用
void lvIME_InitStyle(void)
{
  lvIME_Clipboard.Content[0] = '\0'; //开机剪切板初始化

  //无边界全铺满样式
  lv_style_init(&TMStyle_NullBG);
  lv_style_set_pad_all(&TMStyle_NullBG, 0);
  lv_style_set_pad_gap(&TMStyle_NullBG, 0);
  lv_style_set_clip_corner(&TMStyle_NullBG, true);
  lv_style_set_radius(&TMStyle_NullBG, LV_RADIUS_CIRCLE);
  lv_style_set_border_width(&TMStyle_NullBG, 0);
  //矩形按钮铺满样式
  lv_style_init(&TMStyle_BtnFull);
  lv_style_set_radius(&TMStyle_BtnFull, 0);
  lv_style_set_border_width(&TMStyle_BtnFull, 1);
  lv_style_set_border_opa(&TMStyle_BtnFull, LV_OPA_50);
  lv_style_set_border_color(&TMStyle_BtnFull, lv_palette_main(LV_PALETTE_GREY));
  lv_style_set_border_side(&TMStyle_BtnFull, LV_BORDER_SIDE_INTERNAL);
  //半透明样式
  lv_style_init(&TMStyle_HalfOpa);
  lv_style_set_bg_opa(&TMStyle_HalfOpa, LV_OPA_50);
  //lv_style_set_border_opa(&TMStyle_HalfOpa, LV_OPA_50);
  //lv_style_set_radius(&TMStyle_HalfOpa, 1);
}

//-------------------------------全局样式退出--------------------------------
//退出lvIME时须调用
void lvIME_ResetStyle(void)
{
  lv_style_reset(&TMStyle_NullBG);
  lv_style_reset(&TMStyle_BtnFull);
  lv_style_reset(&TMStyle_HalfOpa);
}

//-------------------------------创建输入法---------------------------------
//默认输入法：默认输入法,>=0为原T9或导航输入法，<0为触摸输入法，0xff为上次触模输入法
//返回NULL失败，否则为主对像
lv_obj_t * lvIME_Create(lv_obj_t * pParent,   //父窗口
                         union _lvIME *pIME, //主结构
                         lvIME_EndCb_t pEndCb, //退出回调
                         void *pvEndCb,        //退出回调参数
                         char *pString,          //用户已存在的字符串,必须以'\0'结尾
                         unsigned short Size,     //字符串缓冲区允许大小+1
                         signed char DefaultType, //默认输入法
                         unsigned char TypeMask,//可使用的输入法类型
                         const char *pSignTbl, //挂接的符号表,为空时使用默认
                         unsigned short Cursor) //默认光标位置,-1时为最后
{
  _pOrgParent = pParent;
  _OrgTypeMask = TypeMask;
  if(DefaultType >= 0){//>=0为原T9或导航输入法
    #ifdef SUPPORT_LV_IME_T9
      //if(DefaultType > 4) DefaultType = 0;
      if(lvIME_T9Create(pParent,   //父窗口
                          &pIME->T9, //主结构
                          pEndCb, pvEndCb, //退出回调及参数
                          pString, //用户已存在的字符串,必须以'\0'结尾
                          Size,     //字符串缓冲区允许大小
                          DefaultType,   //默认输入法,<4
                          TypeMask,//可使用的输入法类型
                          pSignTbl, //挂接的符号表,为空时使用默认
                          Cursor)){//默认光标位置
        lvIME_RType = LVIME_RTYPE_T9;
        return pIME->T9.pObj;//创建不成功!
      }
      return NULL;
    #elif defined(SUPPORT_LV_IME_GUIDE)  //导航输入法时
      //if(DefaultType > 4) DefaultType = 0;
      if(lvIME_GuideCreate(pParent,   //父窗口
                          &pIME->Guide, //主结构
                          pEndCb, pvEndCb, //退出回调及参数
                          pString, //用户已存在的字符串,必须以'\0'结尾
                          Size,     //字符串缓冲区允许大小
                          DefaultType,   //默认输入法,<4
                          TypeMask,//可使用的输入法类型
                          pSignTbl, //挂接的符号表,为空时使用默认
                          Cursor)){//默认光标位置
        lvIME_RType = LVIME_RTYPE_GUIDE;
        return pIME->Guide.pObj;//创建不成功!
      }
      return NULL;
    #else //原T9或导航输入法都不支持时
      DefaultType = LVIME_TYPE_SEL;
    #endif
  }
  //<0为触摸输入法
  #ifdef SUPPORT_LV_IME_TOUCH//支持触模输入法时
    if(lvIME_TouchCreate(pParent,   //父窗口
                          &pIME->Touch, //主结构
                          pEndCb, pvEndCb, //退出回调及参数
                          pString, //用户已存在的字符串,必须以'\0'结尾
                          Size,     //字符串缓冲区允许大小
                          DefaultType,   //默认输入法,<4
                          TypeMask,//可使用的输入法类型
                          pSignTbl, //挂接的符号表,为空时使用默认
                          Cursor)){//默认光标位置

      lvIME_RType = LVIME_RTYPE_TOUCH;
      return pIME->Touch.pObj;//创建不成功!
    }
    return NULL;
  #endif

  return NULL;
}

//----------------------------------刷新任务--------------------------------
//128ms调用一次
void lvIME_RefreshTask(union _lvIME *pIME)
{
  #ifdef SUPPORT_LV_IME_T9
    if(lvIME_RType == LVIME_RTYPE_T9){
      if(TImeMng_Task(&pIME->T9.Ime)) lvIME_T9Refresh(&pIME->T9);
    }
  #elif defined(SUPPORT_LV_IME_GUIDE)
    if(lvIME_RType == LVIME_RTYPE_GUIDE){
      if(TImeMng_Task(&pIME->Guide.Ime)) lvIME_GuideRefresh(&pIME->Guide);
    }
  #endif
}

//-----------------------------主动删除输入法---------------------------------
void lvIME_Delete(union _lvIME *pIME)
{
  if(lvIME_RType < 0) return;  //已不在输入法状态
  #ifdef SUPPORT_LV_IME_T9
    if(lvIME_RType == LVIME_RTYPE_T9) lvIME_T9Delete(&pIME->T9);
  #elif defined(SUPPORT_LV_IME_GUIDE)
    if(lvIME_RType == LVIME_RTYPE_GUIDE) lvIME_GuideDelete(&pIME->Guide);
  #endif

  #ifdef SUPPORT_LV_IME_TOUCH
    if(lvIME_RType == LVIME_RTYPE_TOUCH) lvIME_TouchDelete(&pIME->Touch);
  #endif
  lvIME_RType = -1;  //退出
}

/*******************************************************************************
                          各运行时实现回调函数
*******************************************************************************/

//----------------------T9或导航输入法切换至触模输入法--------------------------
static unsigned char _TIme2Type[] = {
  LVIME_TYPE_PINYIN26, //T9或导航内拼音输入法
  LVIME_TYPE_NUM, //数字输入
  LVIME_TYPE_L_LETTER,//小写字母
  LVIME_TYPE_U_LETTER,//大写字母
  LVIME_TYPE_SIGN,//符号输入
};

//------------------------触模输入法切换到导航输入法---------------------------
//前5项直接对应，第6项开始
static unsigned char _Type2TIme[] = {
  LVIME_TYPE_NUM,   //输入法选择键盘模式
  LVIME_TYPE_U_LETTER, //T9输入法,为完整输入法,用于选择
  LVIME_TYPE_L_LETTER, //导航输入法,为完整输入法,用于选择
  LVIME_TYPE_PINYIN9,//9键拼音输入
  LVIME_TYPE_PINYIN26,//26键拼音输入
  LVIME_TYPE_SIGN,  //定制符号输入
};

//----------------------------T9切换至其它输入法------------------------------
#ifdef SUPPORT_LV_IME_T9
void lvIME_cbT9ToOtherIME(struct _lvIME_T9 *pIME,
                          unsigned char Key)//LV_KEY_HOME or LV_KEY_END
{
  #ifdef SUPPORT_LV_IME_TOUCH
    unsigned char DefaultType;
    if(Key == LV_KEY_HOME) DefaultType = LVIME_TYPE_SEL;
    else DefaultType = _TIme2Type[pIME->Ime.Type];
    lvIME_TouchCreate(_pOrgParent,   //父窗口
                      &((union _lvIME*)pIME)->Touch, //主结构
                      pIME->pEndCb, pIME->pvEndCb, //退出回调及参数
                      pIME->pString, //用户已存在的字符串,必须以'\0'结尾
                      pIME->Size,     //字符串缓冲区允许大小
                      DefaultType,   //默认输入法,<4
                      _OrgTypeMask,//可使用的输入法类型
                      pIME->Ime.pSignTbl, //挂接的符号表,为空时使用默认
                      0);//默认光标位置
    lvIME_RType = LVIME_RTYPE_TOUCH;
  #endif
}

//--------------------------导航输入法切换至其它输入法---------------------------
#elif defined(SUPPORT_LV_IME_GUIDE)
void lvIME_cbGuideToOtherIME(struct _lvIME_Guide *pIME,
                            unsigned char Key)//LV_KEY_HOME or LV_KEY_END
{
  #ifdef SUPPORT_LV_IME_TOUCH
    unsigned char DefaultType;
    if(Key == LV_KEY_HOME) DefaultType = LVIME_TYPE_SEL;
    else DefaultType = _TIme2Type[pIME->Ime.Type];
    lvIME_TouchCreate(_pOrgParent,   //父窗口
                      &((union _lvIME*)pIME)->Touch, //主结构
                      pIME->pEndCb, pIME->pvEndCb, //退出回调及参数
                      pIME->pString, //用户已存在的字符串,必须以'\0'结尾
                      pIME->Size,     //字符串缓冲区允许大小
                      DefaultType,   //默认输入法,<4
                      _OrgTypeMask,//可使用的输入法类型
                      pIME->Ime.pSignTbl, //挂接的符号表,为空时使用默认
                      0);//默认光标位置
    lvIME_RType = LVIME_RTYPE_TOUCH;
  #endif
}
#endif

//----------------------------切换至T9或导航输入法------------------------------
#ifdef SUPPORT_LV_IME_TOUCH
#if defined(SUPPORT_LV_IME_T9) || defined(SUPPORT_LV_IME_GUIDE)
void lvIME_cbTouchToT9Guide(struct _lvIME_Touch *pIME)
{
  unsigned char DefaultType = pIME->CurIME;
  if(DefaultType > TIME_TYPE_SIGN)
    DefaultType = _Type2TIme[DefaultType - (TIME_TYPE_SIGN + 1)];
  #ifdef SUPPORT_LV_IME_T9
    lvIME_T9Create(_pOrgParent,   //父窗口
                    &((union _lvIME*)pIME)->T9, //主结构
                    pIME->pEndCb, pIME->pvEndCb, //退出回调及参数
                    pIME->pString, //用户已存在的字符串,必须以'\0'结尾
                    pIME->Size,     //字符串缓冲区允许大小
                    DefaultType,   //默认输入法,<4
                    _OrgTypeMask,//可使用的输入法类型
                    pIME->pSignTbl, //挂接的符号表,为空时使用默认
                    0);//默认光标位置
    lvIME_RType = LVIME_RTYPE_T9;
  #else //导航输入法时
    lvIME_GuideCreate(_pOrgParent,   //父窗口
                     &((union _lvIME*)pIME)->Guide, //主结构
                    pIME->pEndCb, pIME->pvEndCb, //退出回调及参数
                    pIME->pString, //用户已存在的字符串,必须以'\0'结尾
                    pIME->Size,     //字符串缓冲区允许大小
                    DefaultType,   //默认输入法,<4
                    _OrgTypeMask,//可使用的输入法类型
                    pIME->pSignTbl, //挂接的符号表,为空时使用默认
                    0);//默认光标位置
      lvIME_RType = LVIME_RTYPE_GUIDE;
    }
  #endif
}
#endif
#endif //SUPPORT_LV_IME_TOUCH
